﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using Medianamik.Client.Data.Repositories;
using Medianamik.Core;
using Medianamik.Core.DAL;
using Medianamik.Core.DAL.Repositories;
using Medianamik.Core.DAL.Services;
using Medianamik.Core.Interfaces;
using SubSonic;

namespace Medianamik.UI.Web.Approbation.Data
{
    public class ApprobationRepository : IApprobationRepository<ApprobationDTO>
    {

        public PagedCollection<ApprobationDTO> GetPagedPendingApprobations(CultureInfo culture, 
            string groupsIds, bool immediateApprobations, bool publishingOnly, int pageSize, int pageIndex)
        {
            var approbations = new List<ApprobationDTO>();
            
            using(var reader = SPs.MedianamikGetPendingApprobationByGroupId(publishingOnly,
                immediateApprobations, groupsIds, culture.Name, pageSize, pageIndex).GetReader())
            {
                while (reader.Read())
                {
                    approbations.Add(ToApprobation(reader, publishingOnly));
                }
            }
 
            return new  PagedCollection<ApprobationDTO>(approbations,
                GetPendingApprobationsCount(culture, groupsIds, immediateApprobations, publishingOnly));
        }

        public PagedCollection<ApprobationDTO> GetPagedPendingPublications(CultureInfo culture, bool publishingOnly, int pageSize, int pageIndex)
        {
            var approbations = new List<ApprobationDTO>();

            var nodes = NodeManager.GetModifiedNodes(MedianamikContext.Current.EditionCulture,
                                    MedianamikTypes.BaseType,
                                    MedianamikModules.ContentManagement);

            nodes.Skip((pageIndex - 1) * pageSize).Take(pageSize).ForEach(n => approbations.Add(ToApprobation(n, publishingOnly)));

            return new  PagedCollection<ApprobationDTO>(approbations, nodes.Count);
        }

        public int GetPendingApprobationsCount(CultureInfo culture, string groupId, 
            bool immediateApprobations, bool publishingOnly)
        {
            return Convert.ToInt32(SPs.MedianamikGetPendingApprobationByGroupIdCount(
                                            immediateApprobations,
                                            groupId,
                                            culture == null ? default(string) :  culture.Name,
                                            publishingOnly
                                        ).ExecuteScalar());
        }

        private static ApprobationDTO ToApprobation(IDataReader reader, bool publish)
        {
            return new ApprobationDTO
                {
                    NodeId = new Guid(reader["nodeid"].ToString()),
                    Name = reader["name"].ToString(),
                    ApprobationLevel = Convert.ToInt32(reader["approbationlevel"]),
                    ModifiedBy = reader["modifiedby"].ToString(),
                    ModifiedOn = DateTime.Parse(reader["modifiedon"].ToString()),
                    CultureName = reader["culturename"].ToString(),
                    TypeId =  new Guid(reader["typeid"].ToString()),
                    Publish = publish 
                };
        }

        private static ApprobationDTO ToApprobation(Node node, bool publish)
        {
            return new ApprobationDTO
            {
                NodeId = node.NodeId,
                Name = node.Name,
                ApprobationLevel = 0,
                ModifiedBy = node.EditedBy,
                ModifiedOn = node.ModifiedOn,
                CultureName = node.CultureName,
                TypeId = node.TypeId,
                Publish = publish
            };
        }

        #region Implementation of INodeRepository

        public INodeWrapper NewNode(IMedianamikDTO dto)
        {
            throw new NotImplementedException();
        }

        public INodeWrapper NewNode(IMedianamikDTO dto, bool validateHierarchicalRules)
        {
            throw new NotImplementedException();
        }

        public INodeWrapper GetExistingNode(IMedianamikDTO dto)
        {
            throw new NotImplementedException();
        }

        public void SaveNode(INodeWrapper node)
        {
            throw new NotImplementedException();
        }

        public void PublishNode(INodeWrapper node, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public void SaveNodeHandlingPositionAndParentNodeId(INodeWrapper node, Guid? parentNodeId, short? position)
        {
            throw new NotImplementedException();
        }

        public void PublishNodeHandlingPositionAndParentNodeId(INodeWrapper node, Guid? parentNodeId, short? position, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public void Reorder(Guid id, Guid destinationId, DropPosition position)
        {
            throw new NotImplementedException();
        }

        public void SetActiveStatus(Guid id, CultureInfo culture, ActiveStatus status)
        {
            throw new NotImplementedException();
        }

        public void SaveNodes(IEnumerable<Node> nodes)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region Implementation of IMedianamikRepository<ApprobationDTO>

        public INodeMapper NodeMapper
        {
            get { throw new NotImplementedException(); }
        }

        public ICultureService CultureService
        {
            get { throw new NotImplementedException(); }
        }

        public IContentStateService ContentStateService
        {
            get { throw new NotImplementedException(); }
        }

        public PagedCollection<ApprobationDTO> PagedWithFilters(CultureInfo editionCulture, int pageIndex, int pageSize, ActiveStatus contentStatus, Guid? baseTypeId, Guid? moduleNodeId, DateTime? startDate, DateTime? endDate, string keywords, string orderBy, IEnumerable<Where> additionalWheres, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public PagedCollection<ApprobationDTO> PagedWithFilters(bool multiLingual, CultureInfo culture, int pageIndex, int pageSize, ActiveStatus status, Guid? typeId, Guid? parentId, DateTime? startDate, DateTime? endDate, string keywords, string orderBy, IEnumerable<Where> additionalWheres, IEnumerable<BetweenAnd> additionalBetweenAnds, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public PagedCollection<ApprobationDTO> PagedWithFilters(CultureInfo editionCulture, int pageIndex, int pageSize, Guid baseTypeId, Guid moduleNodeId, IEnumerable<Where> additionalWheres)
        {
            throw new NotImplementedException();
        }

        public ApprobationDTO Get(Guid nodeId)
        {
            throw new NotImplementedException();
        }

        public ApprobationDTO Get(Guid nodeId, CultureInfo culture, ContentState contentState)
        {
            throw new NotImplementedException();
        }

        public ApprobationDTO Get(Guid nodeId, CultureInfo culture, ContentState contentState, ActiveStatus activeStatus)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> GetWithFilters(Guid? typeId, Guid? parentId, IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public PagedCollection<ApprobationDTO> PagedWithFilters(int pageIndex, int pageSize, Guid? typeId, Guid? parentId, IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> ChildsOf(Guid nodeId, bool inclusive, int maxDepth)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> ParentsOf(Guid nodeId, bool inclusive, int maxDepth)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<ApprobationDTO> LoadByIDs(string ids)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<ApprobationDTO> LoadByIDs(IList<Guid> ids)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> All()
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> GetWithFilters(CultureInfo culture, ContentState contentState, ActiveStatus status, Guid? typeId, Guid? parentId, IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public PagedCollection<ApprobationDTO> PagedWithFilters(CultureInfo culture, ContentState contentState, ActiveStatus status, int pageIndex, int pageSize, Guid? typeId, Guid? parentId, IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public PagedCollection<ApprobationDTO> PagedWithFilters(bool multiLingual, CultureInfo culture, ContentState contentState, ActiveStatus status, int pageIndex, int pageSize, Guid? typeId, Guid? parentId, IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> ChildsOf(Guid nodeId, bool inclusive, int maxDepth, CultureInfo culture, ContentState contentState, ActiveStatus status)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> ParentsOf(Guid nodeId, bool inclusive, int maxDepth, CultureInfo culture, ContentState contentState, ActiveStatus status)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<ApprobationDTO> LoadByIDs(string ids, string cultureName, ContentState contentState, ActiveStatus status)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<ApprobationDTO> LoadByIDs(IList<Guid> ids, string cultureName, ContentState contentState, ActiveStatus status)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> All(CultureInfo culture, ContentState contentState, ActiveStatus status)
        {
            throw new NotImplementedException();
        }

        public void DeleteByParent(Guid parendId, bool destroy)
        {
            throw new NotImplementedException();
        }

        public void DeleteBranch(Guid nodeId, bool destroy)
        {
            throw new NotImplementedException();
        }

        public void Delete(ApprobationDTO item)
        {
            throw new NotImplementedException();
        }

        public void MapAndSaveItem<T>(T item) where T : IMedianamikDTO
        {
            throw new NotImplementedException();
        }

        public void MapAndSaveItem<T>(T item, MappingOptions options) where T : IMedianamikDTO
        {
            throw new NotImplementedException();
        }

        public void MapAndSaveItems<T>(IEnumerable<T> item) where T : IMedianamikDTO
        {
            throw new NotImplementedException();
        }

        public void MapAndSaveItems<T>(IEnumerable<T> item, MappingOptions options) where T : IMedianamikDTO
        {
            throw new NotImplementedException();
        }

        public void MapAndPublishItem<T>(T item) where T : IMedianamikDTO
        {
            throw new NotImplementedException();
        }

        public void MapAndPublishItem<T>(T item, MappingOptions options) where T : IMedianamikDTO
        {
            throw new NotImplementedException();
        }

        public void MapAndPublishItems<T>(IEnumerable<T> item) where T : IMedianamikDTO
        {
            throw new NotImplementedException();
        }

        public void MapAndPublishItems<T>(IEnumerable<T> item, MappingOptions options) where T : IMedianamikDTO
        {
            throw new NotImplementedException();
        }

        public void Delete(Guid nodeId, bool destroy)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> GetWithFilters(bool multiLingual, CultureInfo culture, ActiveStatus status, Guid? typeId, Guid? parentId, DateTime? startDate, DateTime? endDate, string keywords, string orderBy, IEnumerable<Where> additionalWheres, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> AllInstances()
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> AllInstances(ContentState contentState, ActiveStatus status)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> AllInstances(Guid nodeId)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> AllInstances(Guid nodeId, ContentState contentState, ActiveStatus status)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> AlllInstancesWithFilters(ContentState contentState, ActiveStatus status, Guid? typeId, Guid? parentId, IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        public IList<ApprobationDTO> AlllInstancesWithFilters(Guid? typeId, Guid? parentId, IEnumerable<Where> wheres, IEnumerable<BetweenAnd> betweensAnd, string orderByString, int? depth, bool withTypeInheritance)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public interface IApprobationRepository<T> : IMedianamikRepository<T> where T : IMedianamikDTO
    {
        PagedCollection<ApprobationDTO> GetPagedPendingApprobations(CultureInfo culture, 
            string groupsIds, bool immediateApprobations, bool publishingOnly, int pageSize, int pageIndex);

        int GetPendingApprobationsCount(CultureInfo culture, string groupId, bool immediateApprobations, 
            bool publishingOnly);

        PagedCollection<ApprobationDTO> GetPagedPendingPublications(CultureInfo culture, bool publishingOnly,
                                                                    int pageSize, int pageIndex);
    }
}